package killerqueen.game.main;

import java.util.ArrayList;
import java.util.List;

import killerqueen.game.interfaces.GameObject;
import killerqueen.game.objects.Bullet;
import killerqueen.game.objects.Player;
import killerqueen.game.xml.loader.XML2GameObjects;

import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.World;
import org.newdawn.slick.AppGameContainer;
import org.newdawn.slick.BasicGame;
import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

public class GameMain extends BasicGame {

        private static final int SCREEN_W = 800;
        private static final int SCREEN_H = 600;
		private static List<GameObject> readyToAdd;
		private static List<GameObject> readyToKill;

        float scale_factor;
        private boolean playerFocus;
        private Vec2 cameraFocus;
        private Player player;
        private World world;
        private List<GameObject> gameObjects;

        public GameMain() {
                super("Punctum");
        }

        @Override
        public void init(GameContainer gc) throws SlickException {

                world = new World(new Vec2(0.0f, -10.0f), true);
                cameraFocus = new Vec2();
                XML2GameObjects xml2GameObjects = new XML2GameObjects();

                world.setContactListener(new GameContactListener());
                gc.getInput().addMouseListener(new MainMouseListener(this));

                scale_factor = 25;
                playerFocus = true;

                xml2GameObjects.load(
                                ClassLoader.getSystemResourceAsStream("levels/level1.xml"),
                                world);
                gameObjects = xml2GameObjects.getGameObjectList();
                player = (Player) xml2GameObjects.getPlayer();
                gameObjects.add(player);
                
                readyToAdd = new ArrayList<GameObject>();
                readyToKill = new ArrayList<GameObject>();

                gc.setShowFPS(true);
                gc.setMinimumLogicUpdateInterval(17);
        }

        @Override
        public void render(GameContainer gc, Graphics g) throws SlickException {

                g.setBackground(Color.lightGray);
                Vec2 pos;
                if (playerFocus) {
                        pos = player.getBody().getPosition();
                } else {
                        pos = cameraFocus;
                }

                // draw background
                g.pushTransform();
                // draw main ground

                float xs = pos.x * scale_factor - SCREEN_W / 2;
                float ys = -pos.y * scale_factor - SCREEN_H / 2;

                g.setAntiAlias(true);

                g.translate(-xs, -ys);
                g.scale(scale_factor, -scale_factor);

                for (GameObject gameObject : gameObjects) {
                        gameObject.paint(g);
                }

                // draw front ground
                g.popTransform();
                // draw interface overlay
                g.drawString(player.getBody().getLinearVelocity()+"",10,25);

        }

        @Override
        public void update(GameContainer gc, int delta) throws SlickException {
                Input input = gc.getInput();
                if (input.isKeyDown(Input.KEY_P)) {
                        gc.pause();
                }
                if (input.isKeyDown(Input.KEY_R)) {
                        gc.resume();
                }
                if (input.isKeyDown(Input.KEY_LEFT)) {
                        if (playerFocus) {
                                cameraFocus = new Vec2(player.getBody().getPosition());
                                ;
                                playerFocus = false;
                        }
                        cameraFocus.x--;
                }
                if (input.isKeyDown(Input.KEY_RIGHT)) {
                        if (playerFocus) {
                                cameraFocus = new Vec2(player.getBody().getPosition());
                                ;
                                playerFocus = false;
                        }
                        cameraFocus.x++;
                }
                if (input.isKeyDown(Input.KEY_UP)) {
                        if (playerFocus) {
                                cameraFocus = new Vec2(player.getBody().getPosition());
                                ;
                                playerFocus = false;
                        }
                        cameraFocus.y++;
                }
                if (input.isKeyDown(Input.KEY_DOWN)) {
                        if (playerFocus) {
                                cameraFocus = new Vec2(player.getBody().getPosition());
                                ;
                                playerFocus = false;
                        }
                        cameraFocus.y--;
                }

                if (input.isKeyDown(Input.KEY_Y)) {
                        if (!playerFocus) {
                                playerFocus = true;
                        }
                }

                for (GameObject gameObject : gameObjects) {
                        gameObject.input(input);
                }

                for (GameObject gameObject : gameObjects) {
                        gameObject.update(delta);
                }
                
                world.step(delta / 1000f, 6, 2);
                
                for (GameObject object : readyToAdd) {
					object.init(world, "");
					gameObjects.add(object);
				}
                readyToAdd.clear();
                for (GameObject object : readyToKill) {
                	object.destroy(world);
					gameObjects.remove(object);
				}

        }
        
       

        public static void main(String[] args) throws SlickException {
                AppGameContainer app = new AppGameContainer(new GameMain());
                app.setDisplayMode(SCREEN_W, SCREEN_H, false);
                app.start();
        }

		public static void insertObject(GameObject object) {
			readyToAdd.add(object);
			
		}
		
		public static void destroyObject(GameObject object) {
			readyToKill.add(object);
			
		}
}